#-*- coding: UTF-8 -*-
from pyramid.httpexceptions import HTTPFound
from pyramid.security import remember
from pyramid.security import forget

from sqlalchemy import and_
from sqlalchemy import or_
from sqlalchemy.orm import eagerload


from scp.modelo.models import DBSession
from scp.modelo.Tipo_Item import Tipo_Item
from scp.modelo.Rol import Rol
from scp.modelo.Permiso import Permiso
from scp.modelo.Item import Item
from scp.modelo.Fase import Fase
from scp.modelo.ValoresCadena import ValoresCadena
from scp.modelo.ValoresNumerico import ValoresNumerico
from scp.modelo.ValoresFecha import ValoresFecha
from scp.modelo.RelacionP_H import RelacionP_H
from scp.modelo.RelacionA_S import RelacionA_S

from pyramid.response import Response
from pyramid.view import view_config
import json

import re

session = DBSession()
#@view_config(renderer='json')
def relaciones(request):
	"""Método controlador encargado de la administración de las relaciones.
		URL asociada: /relaciones/{operacion}
		operacion:
			traerItems: retorna los items a relacionar de acuerdo al tipo de relacion
		@param request: Petición Http del cliente. 	
	"""
	
	methodRequest = request.method
		
	dicParametros = request.matchdict
	

	if dicParametros.get('operacion') == 'crear' and request.url.find('?') == -1:
		print 'respondí un diccionario normal'
		return {'content':'Hello!'}	
	
	
	
	if dicParametros.get('operacion') == 'traerItemsCrear':
		tipoRelacion = request.params['tipoRelacion']
		nombreProyecto = request.params['nombreProyecto']
		idFase = request.params['idFase']
		idItem = request.params['idItem']
		print 'Este es el id de la fase:'
		print idFase
		
		response = Response()
		if tipoRelacion == 'Padre - Hijo':
			hijo = session.query(RelacionP_H).filter_by(hijo = idItem).first()
			itemElegido = session.query(Item).filter_by(id = idItem).first()
			if itemElegido.estado == 'BLOQUEADO':
				items = session.query(Item).filter(and_(Item.fase_id==request.params['idFase'], Item.flagUltimo == 1, Item.flagBorrado == 0, Item.id != idItem)).filter(Item.estado == 'BLOQUEADO').all()
			else:
				items = session.query(Item).filter(and_(Item.fase_id==request.params['idFase'], Item.flagUltimo == 1, Item.flagBorrado == 0, Item.id != idItem)).filter(or_(Item.estado == 'APROBADO', Item.estado == 'BLOQUEADO')).all()
			padresArray = []
			if hijo is None:
				for item in items:
					aux = {'idItem':item.id, 'nombreItem':item.nombre}
					padresArray.append(aux)
			response.body = json.dumps(dict(success = True, items = padresArray))
			
		else:
			fase = session.query(Fase).filter_by(id = idFase).first()
			proyectoID = fase.proyecto_id
			antecesoresArray = []
			if fase.orden > 1:
				faseAnterior = session.query(Fase).filter_by(orden = fase.orden - 1, proyecto_id = proyectoID).first()
				items = session.query(Item).filter(and_(Item.fase_id==faseAnterior.id, Item.flagUltimo == 1, Item.flagBorrado == 0, Item.id != idItem, Item.estado == 'BLOQUEADO')).all()
				print '>>>len(items)'
				print len(items)
				for item in items:
					aux = {'idItem':item.id, 'nombreItem':item.nombre}
					antecesoresArray.append(aux)
			response.body = json.dumps(dict(success = True, items = antecesoresArray))
				
		response.content_type = 'application/json'
		
		return response

	if dicParametros.get('operacion') == 'traerItem':
		idItem = request.params['idItem']
		item = session.query(Item).filter_by(id = idItem).first()
		
		response = Response()
		response.body = json.dumps(dict(success = True, item = {'codItem': item.codigo, 'nombreItem': item.nombre, 'versionItem': item.version}))
		response.content_type = 'application/json'
		
		return response
	
	if dicParametros.get('operacion') == 'view':
		idItem = request.params['idItem']
		relacionesArray = []

		print ">>>request.params['idItem'] en relaciones"
		print request.params['idItem']

		tipoRelacion = 'Padre-Hijo'
		relaciones = session.query(RelacionP_H).filter(or_(RelacionP_H.padre == idItem, RelacionP_H.hijo == idItem)).all()
		for relacion in relaciones:
			duenho = None
			padre = session.query(Item).filter_by(id = relacion.padre, flagUltimo = 1, flagBorrado = 0).first()
			hijo = session.query(Item).filter_by(id = relacion.hijo, flagUltimo = 1, flagBorrado = 0).first()
			duenho = session.query(Item).filter_by(id = relacion.duenho, flagUltimo = 1, flagBorrado = 0).first()
			
			if (hijo is not None) and (padre is not None):
				if str(duenho.id) == str(idItem):
					duenho = True
					item = padre.nombre
					
				else:
					duenho = False
					item = hijo.nombre
					
					
			
				aux = {'idRelacion': relacion.id, 'item':item, 'tipoRelacion':tipoRelacion, 'duenho': duenho}
				relacionesArray.append(aux)
		
		tipoRelacion = 'Antecesor-Sucesor'
		relaciones = session.query(RelacionA_S).filter(or_(RelacionA_S.antecesor == idItem, RelacionA_S.sucesor == idItem)).all()
		for relacion in relaciones:
			duenho = None
			antecesor = session.query(Item).filter_by(id = relacion.antecesor, flagUltimo = 1, flagBorrado = 0).first()
			sucesor = session.query(Item).filter_by(id = relacion.sucesor, flagUltimo = 1, flagBorrado = 0).first()
			duenho = session.query(Item).filter_by(id = relacion.duenho, flagUltimo = 1, flagBorrado = 0).first()
			
			if (antecesor is not None) and (sucesor is not None):
				if str(duenho.id) == str(idItem):
					duenho = True
					item = antecesor.nombre
					
				else:
					duenho = False
					item = sucesor.nombre
					
				
				aux = {'idRelacion': relacion.id, 'item':item, 'tipoRelacion':tipoRelacion, 'duenho': duenho}
				relacionesArray.append(aux)
			
		response = Response()
		response.body = json.dumps(dict(success = True, relaciones = relacionesArray))
		response.content_type = 'application/json'
		
		return response
		
	if dicParametros.get('operacion') == 'create':
		tipoRelacion = request.params['tipoRelacion']
		idItem = request.params['idItem']
		idItemRelacionar = request.params['idItemRelacionar']
		
		response = Response()
		if tipoRelacion == 'Padre - Hijo':
			ciclo = comprobar_ciclos(idItem, idItemRelacionar)
			print 'ciclo'
			print ciclo
			if (ciclo == True):
				response.body = json.dumps(dict(success = False, msg = 'No se puede crear la relacion, se formara un ciclo!!!'))
			else:
				relacionP_H = RelacionP_H()
				relacionP_H.padre = idItemRelacionar
				relacionP_H.hijo = idItem
				relacionP_H.duenho = idItem
				
				session.add(relacionP_H)
				response.body = json.dumps(dict(success = True))
			
		else:
			existe_relacion = session.query(RelacionA_S).filter_by(antecesor = idItemRelacionar, sucesor = idItem).first()
			if (not existe_relacion):
				relacionA_S = RelacionA_S()
				relacionA_S.antecesor = idItemRelacionar
				relacionA_S.sucesor = idItem
				relacionA_S.duenho = idItem
			
				session.add(relacionA_S)
		
		
		
		response.content_type = 'application/json'
		
		return response
		
	if dicParametros.get('operacion') == 'traerItemsEditar':
		tipoRelacion = request.params['tipoRelacion']
		nombreProyecto = request.params['nombreProyecto']
		idFase = request.params['idFase']
		idItem = request.params['idItem']
		
		response = Response()
		if tipoRelacion == 'Padre - Hijo':
			itemElegido = session.query(Item).filter_by(id = idItem).first()
			if itemElegido.estado == 'BLOQUEADO':
				items = session.query(Item).filter(and_(Item.fase_id==request.params['idFase'], Item.flagUltimo == 1, Item.flagBorrado == 0, Item.id != idItem)).filter(Item.estado == 'BLOQUEADO').all()
			else:
				items = session.query(Item).filter(and_(Item.fase_id==request.params['idFase'], Item.flagUltimo == 1, Item.flagBorrado == 0, Item.id != idItem)).filter(or_(Item.estado == 'APROBADO', Item.estado == 'BLOQUEADO')).all()
			padresArray = []
			for item in items:
				aux = {'idItem':item.id, 'nombreItem':item.nombre}
				padresArray.append(aux)
			response.body = json.dumps(dict(success = True, items = padresArray))
			
		else:
			fase = session.query(Fase).filter_by(id = idFase).first()
			proyectoID = fase.proyecto_id
			antecesoresArray = []
			if fase.orden > 1:
				faseAnterior = session.query(Fase).filter_by(orden = fase.orden - 1, proyecto_id = proyectoID).first()
				items = session.query(Item).filter(and_(Item.fase_id==faseAnterior.id, Item.flagUltimo == 1, Item.flagBorrado == 0, Item.id != idItem, Item.estado == 'BLOQUEADO')).all()
				for item in items:
					aux = {'idItem':item.id, 'nombreItem':item.nombre}
					antecesoresArray.append(aux)
			response.body = json.dumps(dict(success = True, items = antecesoresArray))
				
		response.content_type = 'application/json'
		
		return response
	
	if dicParametros.get('operacion') == 'edit':
		tipoRelacion = request.params['tipoRelacion']
		idItemRelacionar = request.params['idItemRelacionar']
		idRelacion = request.params['idRelacion']
		idItem = request.params['idItem']
		
		response = Response()
		if tipoRelacion == 'Padre - Hijo':
			ciclo = comprobar_ciclos(idItem, idItemRelacionar)
			if (ciclo == True):
				response.body = json.dumps(dict(success = False, msg = 'No se puede editar la relacion, se formara un ciclo!!!'))
			else:
				relacionP_H = session.query(RelacionP_H).filter_by(id = idRelacion).first()
				relacionP_H.padre = idItemRelacionar
				
				response.body = json.dumps(dict(success = True))
			
		else:
			existe_relacion = session.query(RelacionA_S).filter_by(antecesor = idItemRelacionar, sucesor = idItem).first()
			if (not existe_relacion):
				relacionA_S = session.query(RelacionA_S).filter_by(id = idRelacion).first()
				relacionA_S.antecesor = idItemRelacionar

		response.content_type = 'application/json'
		
		return response
	
	if dicParametros.get('operacion') == 'delete':
		tipoRelacion = request.params['tipoRelacion']
		idRelacion = request.params['idRelacion']
		
		print ">>>id de item a eliminar"
		print idRelacion
		
		response = Response()
		borrado = 'NO'
		if tipoRelacion == 'Padre-Hijo':
			relacionBorrar = session.query(RelacionP_H).filter_by(id = idRelacion ).first()
			hijo = session.query(Item).filter_by(id = relacionBorrar.hijo ).first()
			fase = session.query(Fase).filter_by(id = hijo.fase_id ).first()
			if fase.orden > 1:
				if hijo.estado == 'BLOQUEADO' or hijo.estado == 'APROBADO':
					antecesores = session.query(RelacionA_S.antecesor).filter_by(sucesor = hijo.id ).all()
					for antecesor in antecesores:
						tieneAntecesorActual = session.query(Item).filter_by(id = antecesor[0], flagUltimo = 1, flagBorrado = 0).first()
						if tieneAntecesorActual is not None:
							session.delete(relacionBorrar)
							response.body = json.dumps(dict(success = True))
							borrado = 'SI'
							break 
				else:
					session.delete(relacionBorrar)
					response.body = json.dumps(dict(success = True))
					borrado = 'SI'
			else:
				session.delete(relacionBorrar)
				response.body = json.dumps(dict(success = True))
				borrado = 'SI'
		else:
			relacionBorrar = session.query(RelacionA_S).filter_by(id = idRelacion ).first()
			sucesor = session.query(Item).filter_by(id = relacionBorrar.sucesor ).first()
			if sucesor.estado == 'BLOQUEADO' or sucesor.estado == 'APROBADO':
				padres = session.query(RelacionP_H.padre).filter_by(hijo = sucesor.id ).all()
				for padre in padres:
					tienePadreActual = session.query(Item).filter_by(id = padre[0], flagUltimo = 1, flagBorrado = 0).first()
					if tienePadreActual is not None:
						session.delete(relacionBorrar)
						response.body = json.dumps(dict(success = True))
						borrado = 'SI'
						break
				if borrado == 'NO':
					antecesores = session.query(RelacionA_S.antecesor).filter(RelacionA_S.sucesor == relacionBorrar.sucesor).filter(RelacionA_S.antecesor != relacionBorrar.antecesor).all()
					for antecesor in antecesores:
						tieneAntecesorActual = session.query(Item).filter_by(id = antecesor[0], flagUltimo = 1, flagBorrado = 0).first()
						if tieneAntecesorActual is not None:
							session.delete(relacionBorrar)
							response.body = json.dumps(dict(success = True))
							borrado = 'SI'
							break
			else:
				session.delete(relacionBorrar)
				response.body = json.dumps(dict(success = True))
				borrado = 'SI'
				

		if borrado == 'NO':
			response.body = json.dumps(dict(success = False, msg = 'No se puede eliminar la relacion, el item duenho de la misma quedara inconsistente!!!'))
		
		#responseView.body = json.dumps(dict(success = True, atributos = [{'nombre':'Nombre', 'tipo': 'Cadena'}, {'nombre':'Fecha Inicio', 'tipo': 'Fecha'}]))
		
		response.content_type = 'application/json'
		
		return response
			
def comprobar_ciclos(hijo, padre):
	
	session = DBSession()
	print 'hijo'
	print hijo
	print 'padre'
	print padre
	destinos_relaciones = session.query(RelacionP_H.padre).filter_by(hijo=padre).all()
	print 'destinos_relaciones'
	print destinos_relaciones
	retorno = False 
	
	for destino_relacion in destinos_relaciones:
		print 'destino_relacion'
		print destino_relacion[0]
		itemDestino = session.query(Item).filter_by(id=destino_relacion[0]).one()
		
		if itemDestino.flagUltimo == 1 and itemDestino.flagBorrado == 0:		
			if str(destino_relacion[0]) == str(hijo):
				print 'estoy en el caso base!!!'
				retorno = True
				break
			else:
				retorno = comprobar_ciclos(hijo, destino_relacion[0])
			
	return retorno
